Amazon Machine Learningでサザエさんじゃんけんを予測してみた
サザエさんじゃんけんの予測をAmazon MLでやってみたら6割ぐらいの勝率になりました。ということで、どんな感じでやってみたのか解説します。
前提
- モデル:多項分類
- 目的変数:予測対象となる回のじゃんけんの手
- 説明変数:予測対象となる回の過去n回の手。最大10回。
- 評価データ:100件(第1136回〜第1239回)
- 学習データ:1,089件(第11回〜第1135回)
- Maximum ML model Size:100MB
- Maximum number of data passes:10
- Regularization type (amount):L2, 1e-6 - Mild
評価データが100件とあるのは約1,200件ぐらいあったので、とりあえず直近の100件を予測対象として、それより過去を学習データとすればいいかぐらいのざっくりした考えからです。なお、学習データが100件に対して番組の回数の差が103回あるのはじゃんけんが休みの回は除外しているためです。また、学習データが第11回からなのは最大で過去10回を説明変数として利用しているためです。Maximum ML model Size、Maximum number of data passes、Regularization type (amount)についてはAmazon MLのデフォルト値をそのまま使いました。
今回は予測対象となる手の過去10回分の手を1行のCSVファイルとして作成して、Recipeを使って実際に利用する過去の手の回数を制御しました。
times,target,previous1,previous2,previous3,previous4,previous5,previous6,previous7,previous8,previous9,previous10 第1239回,チョキ,チョキ,グー,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー 第1238回,チョキ,グー,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー,パー 第1237回,グー,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー,パー,チョキ 第1236回,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー,パー,チョキ,グー
Recipeは以下の様な感じです。利用する過去の手の回数が増えるとoutputsの中の変数の数が増えます。
{ "groups": {}, "assignments": {}, "outputs": [ "previous2", "previous1" ] }
Recipeの詳細はAmazon Machine Learning Recipeまとめを参照して下さい。
結果
説明変数の数(過去の手の数)を1〜10に増やしてみた結果は以下のグラフの通りです。過去2回が一番Average F1 scoreが高く、0.59でした。それ以上過去の手を増やしても0.57ぐらいだったので6割ぐらいの正解率でいいなら過去2回分の手があれば十分なようです。
最も正解率が高い過去2回分を利用した際のML model performanceの画面は以下の図の通りです。
おまけ
じゃんけんのデータはサザエさんの過去の手 一覧を利用させていただきました。このページの過去の手のデータを丸ごとコピーしてjanken.txtというファイルに保存します。後は以下のPythonスクリプトでjanken-training.csvとjanken-evaluation.csvが生成されるので、janken-training.csvでモデルを作成し、janken-evaluation.csvで評価します。
# coding: UTF-8 DATA_WINDOW_SIZE = 10 NUM_OF_EVALUATION_RECORDS = 100 records = [] for line in open('janken.txt', 'r'): items = line.split() # 空行を除去 if len(items) == 0: continue # グー/チョキ/パーという文字列に変換(「(観月ありさ)」などの文字列を除去) hand = items[2].split('(')[0] # 休みの行を除去 if hand == '休み': continue records.append({"number_of_times":items[0], "hand":hand}) formated_lines = [] for i, v in enumerate(records): if i + DATA_WINDOW_SIZE >= len(records): break line = v["number_of_times"] + ',' + v["hand"] # 説明変数として利用する過去の手を追加 for j in range(1, 1 + DATA_WINDOW_SIZE): line += ',' + records[i + j]["hand"] formated_lines.append(line) evaluation_file = open("janken-evaluation.csv", "w") training_file = open("janken-training.csv", "w") try: # ヘッダ行の書き込み header = 'times,target' for i in range(1, 1 + DATA_WINDOW_SIZE): header += ',previous' + str(i) evaluation_file.write(header + '\n') training_file.write(header + '\n') for i, v in enumerate(formated_lines): if i < NUM_OF_EVALUATION_RECORDS: evaluation_file.write(v + '\n') else: training_file.write(v + '\n') finally: evaluation_file.close() training_file.close()
まとめ
サザエさんじゃんけんは割りとメジャー?なテーマらしく、8割近くの勝率を出している方もいました!Amazon MLで更に正解率を上げる場合は、学習期間の調整とか追加の変数を探すとかすることになるのかなーと思います。